package com.chenjl.generator.plugin;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.mybatis.generator.api.IntrospectedColumn;
import org.mybatis.generator.api.IntrospectedTable;
import org.mybatis.generator.api.PluginAdapter;
import org.mybatis.generator.api.dom.java.FullyQualifiedJavaType;
import org.mybatis.generator.api.dom.java.Interface;
import org.mybatis.generator.api.dom.java.Method;
import org.mybatis.generator.api.dom.java.TopLevelClass;
import org.mybatis.generator.api.dom.xml.Document;
import org.mybatis.generator.api.dom.xml.XmlElement;

import com.chenjl.generator.Generator;
import com.chenjl.generator.generated.AbstractGenerated;
import com.chenjl.generator.generated.impl.LogicDeleteByPrimaryKeyGenerated;
import com.chenjl.generator.generated.impl.BatchInsertGenerated;
import com.chenjl.generator.generated.impl.BatchLogicDeleteByPrimaryKeyGenerated;
import com.chenjl.generator.generated.impl.BatchSelectByPrimaryKeyGenerated;
import com.chenjl.generator.generated.impl.InsertIgnoreSelectiveGenerated;
import com.chenjl.generator.generated.impl.InsertSelectiveReturnPrimaryKeyGenerated;
import com.chenjl.generator.generated.impl.SelectCountSelectiveGenerated;
import com.chenjl.generator.generated.impl.SelectFirstSelectiveGenerated;
import com.chenjl.generator.generated.impl.SelectLastSelectiveGenerated;
import com.chenjl.generator.generated.impl.SelectPageSelectiveGenerated;

import lombok.extern.slf4j.Slf4j;
/**
 * 扩展mybatis插件
 * 2018-4-12 16:13:15
 * @author chenjinlong
 */
@Slf4j
public class PagePluginAdapter extends PluginAdapter {	
	
	/**
	 * 生成的扩展方法
	 */
	private List<AbstractGenerated> abstractGenerateds = new ArrayList<AbstractGenerated>();
	
	
	public PagePluginAdapter() {
		//3个插入
		abstractGenerateds.add(new InsertSelectiveReturnPrimaryKeyGenerated());
		abstractGenerateds.add(new InsertIgnoreSelectiveGenerated());
		abstractGenerateds.add(new BatchInsertGenerated());
		
		//4个通用查询
		abstractGenerateds.add(new SelectCountSelectiveGenerated());
		abstractGenerateds.add(new SelectPageSelectiveGenerated());
		abstractGenerateds.add(new SelectFirstSelectiveGenerated());
		abstractGenerateds.add(new SelectLastSelectiveGenerated());
		
		//根据id批量获取
		abstractGenerateds.add(new BatchSelectByPrimaryKeyGenerated());
		
		//根据id批量逻辑删除1个，多个
		abstractGenerateds.add(new LogicDeleteByPrimaryKeyGenerated());
		abstractGenerateds.add(new BatchLogicDeleteByPrimaryKeyGenerated());
	}
	
	@Override
	public boolean modelBaseRecordClassGenerated(TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
		//生成model实体类，增加注解setter，getter，toString注解
		Set<FullyQualifiedJavaType> importAnnotations = new HashSet<FullyQualifiedJavaType>();
		importAnnotations.add(new FullyQualifiedJavaType("lombok.Getter"));
		importAnnotations.add(new FullyQualifiedJavaType("lombok.Setter"));
		importAnnotations.add(new FullyQualifiedJavaType("lombok.ToString"));
		topLevelClass.addImportedTypes(importAnnotations);
		
		topLevelClass.addAnnotation("@Setter");
		topLevelClass.addAnnotation("@Getter");
		topLevelClass.addAnnotation("@ToString");
		
		topLevelClass.addJavaDocLine("/**");
		topLevelClass.addJavaDocLine(" * 框架自动生成表模型和CRUD操作，勿修改；");
		topLevelClass.addJavaDocLine(" * 如特殊需要，请以Ext***Mapper自行扩展；");
		topLevelClass.addJavaDocLine(" * 生成日期 : "+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
		topLevelClass.addJavaDocLine(" * @author "+Generator.AUTHOR_NAME);
		topLevelClass.addJavaDocLine(" */");
		return super.modelBaseRecordClassGenerated(topLevelClass, introspectedTable);
	}
	
	@Override
	public boolean modelGetterMethodGenerated(Method method, TopLevelClass topLevelClass,
			IntrospectedColumn introspectedColumn, IntrospectedTable introspectedTable, ModelClassType modelClassType) {
		//不生成属性getter
		return false;
	}
	
	@Override
	public boolean modelSetterMethodGenerated(Method method, TopLevelClass topLevelClass,
			IntrospectedColumn introspectedColumn, IntrospectedTable introspectedTable, ModelClassType modelClassType) {
		//不生成属性setter
		return false;
	}
	
	@Override  
	public boolean clientGenerated(Interface interfaze, TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
		//生成接口java文件
		interfaze.addJavaDocLine("/**");
		interfaze.addJavaDocLine(" * 框架自动生成表模型和CRUD操作，勿修改；");
		interfaze.addJavaDocLine(" * 如特殊需要，请以Ext***Mapper自行扩展；");
		interfaze.addJavaDocLine(" * 生成日期 : "+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
		interfaze.addJavaDocLine(" * @author "+Generator.AUTHOR_NAME);
		interfaze.addJavaDocLine(" */");
		
		interfaze.addImportedType(new FullyQualifiedJavaType("org.springframework.data.domain.Pageable"));
		interfaze.addImportedType(new FullyQualifiedJavaType("org.apache.ibatis.annotations.Param"));
		interfaze.addImportedType(new FullyQualifiedJavaType("java.util.List"));
		interfaze.addImportedType(new FullyQualifiedJavaType("org.springframework.stereotype.Repository"));
		
		interfaze.addAnnotation("@Repository");
		
		//全限定名
		String baseRecordType = introspectedTable.getBaseRecordType();
		
		//生成扩展接口方法
		for(AbstractGenerated abstractGenerated : abstractGenerateds) {
			Method method = abstractGenerated.clientGenerated(baseRecordType);
			interfaze.addMethod(method);
		}
		return super.clientGenerated(interfaze,topLevelClass,introspectedTable);  
	}
	
	@Override  
	public boolean sqlMapDocumentGenerated(Document document, IntrospectedTable introspectedTable) {
		//生产xml文件
		String tableName = introspectedTable.getAliasedFullyQualifiedTableNameAtRuntime();//表名
		String baseRecordType = introspectedTable.getBaseRecordType();//实体类全限定名
		
		List<IntrospectedColumn> columns = introspectedTable.getAllColumns();
		log.info("tableName:{},columns size:{},baseRecordType:{}",tableName,columns.size(),baseRecordType);
		
		XmlElement rootElement = document.getRootElement();//根节点
		
		//生产xml的方法
		for(AbstractGenerated abstractGenerated : abstractGenerateds) {
			XmlElement xmlElement = abstractGenerated.sqlMapDocumentGenerated(introspectedTable,tableName);
			rootElement.addElement(xmlElement);
		}
		
		return super.sqlMapDocumentGenerated(document,introspectedTable);
	}
	
	@Override
	public boolean validate(List<String> args) {
		//是否有效
		return true;
	}
	
}